﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraTabbedMdi;
using Loki.Utils;

namespace Loki.UI.Win
{
    public class MDIContainerViewBase : ViewBase
    {
        protected DevExpress.XtraBars.Bar BAR_Main;
        protected DevExpress.XtraBars.Bar BAR_Status;
        protected XtraTabbedMdiManager MDI_Manager;
        private IContainer components;
        protected DevExpress.XtraNavBar.NavBarControl NAV_Main;

        public MDIContainerViewBase()
            : base()
        {
            InitializeComponent();
            BindNameOnVMState = false;
            MDI_Manager.PageRemoved += MDI_Manager_PageRemoved;
            MDI_Manager.SelectedPageChanged += MDI_Manager_SelectedPageChanged;
            BindingChanged += InitializeBindings;
            BindingChanging += ClearViewModelEvents;
        }

        private void MDI_Manager_SelectedPageChanged(object sender, EventArgs e)
        {
            List<XtraMdiTabPage> l_pages = MDI_Manager.Pages.Cast<XtraMdiTabPage>().ToList();
            foreach (var item in l_pages)
            {
                ViewBase L_Base = item.MdiChild as ViewBase;
                if (L_Base != null && L_Base.ViewModel != null)
                {
                    if (item == MDI_Manager.SelectedPage)
                    {
                        if (!L_Base.ViewModel.IsActive)
                            L_Base.ViewModel.Activate.Execute(null);
                    }
                    else if (L_Base.ViewModel.IsActive)
                        L_Base.ViewModel.Desactivate.Execute(null);
                }
            }
        }

        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, Keys keyData)
        {
            if (keyData == (Keys.Tab | Keys.Control))
            {
                if (MDI_Manager.Pages.Count > 0)
                {
                    XtraMdiTabPage L_LastPage = MDI_Manager.Pages[MDI_Manager.Pages.Count - 1];
                    if (MDI_Manager.SelectedPage != L_LastPage)
                    {
                        MDI_Manager.SelectedPage = MDI_Manager.Pages[MDI_Manager.Pages.IndexOf(MDI_Manager.SelectedPage) + 1];
                        return true;
                    }
                }
                return false;
            }
            else if (keyData == (Keys.Control | Keys.Tab | Keys.Shift))
            {
                if (MDI_Manager.Pages.Count > 0)
                {
                    XtraMdiTabPage L_FirstPage = MDI_Manager.Pages[0];
                    if (MDI_Manager.SelectedPage != L_FirstPage)
                    {
                        MDI_Manager.SelectedPage = MDI_Manager.Pages[MDI_Manager.Pages.IndexOf(MDI_Manager.SelectedPage) - 1];
                        return true;
                    }
                }
                return false;
            }
            else
                return base.ProcessCmdKey(ref msg, keyData);
        }

        /*private void InitializeControls()
        {
            MDI_Manager = new DevExpress.XtraTabbedMdi.XtraTabbedMdiManager(CON_Components);
            DOK_BarAndDockingControler = new DevExpress.XtraBars.DefaultBarAndDockingController(CON_Components);

            ((ISupportInitialize)MDI_Manager).BeginInit();
            ((ISupportInitialize)DOK_BarAndDockingControler.Controller).BeginInit();

            //
            // MDI_Manager
            //
            this.MDI_Manager.ClosePageButtonShowMode = DevExpress.XtraTab.ClosePageButtonShowMode.InAllTabPageHeaders;
            this.MDI_Manager.Controller = this.DOK_BarAndDockingControler.Controller;
            this.MDI_Manager.HeaderButtons = ((DevExpress.XtraTab.TabButtons)((DevExpress.XtraTab.TabButtons.Close | DevExpress.XtraTab.TabButtons.Default)));
            this.MDI_Manager.MdiParent = this;
            this.MDI_Manager.SetNextMdiChildMode = DevExpress.XtraTabbedMdi.SetNextMdiChildMode.TabControl;
            //
            // DOK_BarAndDockingControler
            //
            this.DOK_BarAndDockingControler.Controller.PaintStyleName = "Skin";

            ((ISupportInitialize)DOK_BarAndDockingControler.Controller).EndInit();
            ((ISupportInitialize)MDI_Manager).EndInit();
        }*/

        private void MDI_Manager_PageRemoved(object sender, DevExpress.XtraTabbedMdi.MdiTabPageEventArgs e)
        {
            ViewBase L_View = e.Page.MdiChild as ViewBase;
            if (L_View != null && L_View.ViewModel != null)
                L_View.ViewModel.Close.Execute(L_View.ViewModel);
        }

        private void InitializeBindings(object sender, EventArgs e)
        {
            CreateItems(ViewModel.SubModels);
            this.WatchCollectionChange(ViewModel.SubModels, v => v.ViewModels_CollectionChanged);
        }

        protected void ClearViewModelEvents(object sender, EventArgs e)
        {
            if (ViewModel != null)
                ViewModel.SubModels.CollectionChanged -= ViewModels_CollectionChanged;
        }

        private void CreateItems(IEnumerable P_Models)
        {
            foreach (IViewModel L_Model in P_Models)
            {
                ToolKit.Event.RegisterPropertyChanged(L_Model, ExpressionHelper.GetProperty<IViewModel, bool>(x => x.IsActive), this, (c, s, a) => c.ViewModel_ActivatedChanged(s, a));
                ViewBase L_View = UIContext.Templates.GetView(L_Model) as ViewBase;
                if (L_View != null)
                {
                    L_View.MdiParent = this;
                    L_View.Show();
                }
            }
        }

        private void ViewModels_CollectionChanged(object P_Sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                CreateItems(e.NewItems);
            }
            if (e.OldItems != null)
            {
                foreach (IViewModel L_Model in e.OldItems)
                {
                    ToolKit.Event.UnregisterPropertyChanged(L_Model, ExpressionHelper.GetProperty<IViewModel, bool>(x => x.IsActive), this);
                }
            }
        }

        private void ViewModel_ActivatedChanged(object sender, PropertyChangedEventArgs e)
        {
            List<XtraMdiTabPage> l_pages = MDI_Manager.Pages.Cast<XtraMdiTabPage>().Reverse().ToList();
            foreach (var item in l_pages)
            {
                ViewBase L_Base = item.MdiChild as ViewBase;
                if (L_Base != null && L_Base.ViewModel == sender && L_Base.ViewModel.IsActive)
                    if (MDI_Manager.SelectedPage != item)
                    {
                        MDI_Manager.SelectedPage = item;
                    }
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            List<XtraMdiTabPage> l_pages = MDI_Manager.Pages.Cast<XtraMdiTabPage>().Reverse().ToList();
            foreach (var item in l_pages)
            {
                ViewBase L_Base = item.MdiChild as ViewBase;
                if (L_Base != null)
                {
                    if (L_Base.ViewModel.IsChanged)
                    {
                        if (MessageBoxes.Confirm(Messages.UIMessages.CONFIRM_EXTERNAL_CLOSE, L_Base.Text))
                        {
                            if (MDI_Manager.SelectedPage == item && MDI_Manager.Pages.Count > 1)
                            {
                                MDI_Manager.SelectedPage = MDI_Manager.Pages[MDI_Manager.Pages.IndexOf(item) - 1];
                            }
                            L_Base.ViewModel.AcceptChanges();
                            L_Base.Close();
                        }
                        else
                        {
                            MDI_Manager.SelectedPage = item;
                            e.Cancel = true;
                            return;
                        }
                    }
                    else
                        L_Base.Close();
                }
            }
            base.OnClosing(e);
        }

        public new IContainerViewModel ViewModel
        {
            get { return (IContainerViewModel)base.ViewModel; }
            set { base.ViewModel = value; }
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.BAR_Main = new DevExpress.XtraBars.Bar();
            this.BAR_Status = new DevExpress.XtraBars.Bar();
            this.MDI_Manager = new DevExpress.XtraTabbedMdi.XtraTabbedMdiManager(this.components);
            this.NAV_Main = new DevExpress.XtraNavBar.NavBarControl();
            ((System.ComponentModel.ISupportInitialize)(this.BMA_Main)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.MDI_Manager)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.NAV_Main)).BeginInit();
            this.SuspendLayout();
            //
            // BMA_Main
            //
            this.BMA_Main.Bars.AddRange(new DevExpress.XtraBars.Bar[] {
            this.BAR_Main,
            this.BAR_Status});
            this.BMA_Main.MainMenu = this.BAR_Main;
            this.BMA_Main.StatusBar = this.BAR_Status;
            //
            // BAR_Main
            //
            this.BAR_Main.BarName = "Main";
            this.BAR_Main.CanDockStyle = DevExpress.XtraBars.BarCanDockStyle.Top;
            this.BAR_Main.DockCol = 0;
            this.BAR_Main.DockRow = 0;
            this.BAR_Main.DockStyle = DevExpress.XtraBars.BarDockStyle.Top;
            this.BAR_Main.OptionsBar.AllowQuickCustomization = false;
            this.BAR_Main.OptionsBar.DrawDragBorder = false;
            this.BAR_Main.OptionsBar.DrawSizeGrip = true;
            this.BAR_Main.OptionsBar.MultiLine = true;
            this.BAR_Main.Text = "Main";
            //
            // BAR_Status
            //
            this.BAR_Status.BarName = "Status";
            this.BAR_Status.CanDockStyle = DevExpress.XtraBars.BarCanDockStyle.Bottom;
            this.BAR_Status.DockCol = 0;
            this.BAR_Status.DockRow = 0;
            this.BAR_Status.DockStyle = DevExpress.XtraBars.BarDockStyle.Bottom;
            this.BAR_Status.OptionsBar.AllowQuickCustomization = false;
            this.BAR_Status.OptionsBar.DrawDragBorder = false;
            this.BAR_Status.OptionsBar.UseWholeRow = true;
            this.BAR_Status.Text = "Status";
            //
            // MDI_Manager
            //
            this.MDI_Manager.ClosePageButtonShowMode = DevExpress.XtraTab.ClosePageButtonShowMode.InAllTabPageHeaders;
            this.MDI_Manager.MdiParent = this;
            //
            // NAV_Main
            //
            this.NAV_Main.ActiveGroup = null;
            this.NAV_Main.Dock = System.Windows.Forms.DockStyle.Left;
            this.NAV_Main.Location = new System.Drawing.Point(0, 22);
            this.NAV_Main.MenuManager = this.BMA_Main;
            this.NAV_Main.Name = "NAV_Main";
            this.NAV_Main.OptionsNavPane.ExpandedWidth = 140;
            this.NAV_Main.Size = new System.Drawing.Size(140, 488);
            this.NAV_Main.TabIndex = 5;
            this.NAV_Main.Text = "Main navigation";
            this.NAV_Main.ToolTipController = this.TOO_Controller;
            this.NAV_Main.View = new DevExpress.XtraNavBar.ViewInfo.SkinNavigationPaneViewInfoRegistrator();
            //
            // MDIContainerViewBase
            //
            this.ClientSize = new System.Drawing.Size(943, 533);
            this.Controls.Add(this.NAV_Main);
            this.IsMdiContainer = true;
            this.Name = "MDIContainerViewBase";
            this.Controls.SetChildIndex(this.NAV_Main, 0);
            ((System.ComponentModel.ISupportInitialize)(this.BMA_Main)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.MDI_Manager)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.NAV_Main)).EndInit();
            this.ResumeLayout(false);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }
    }
}